//Client Connection list Manager
//
// Created: Daly 2012-04-01

#include "ax_common.h"
#include "conn_mgr.h"
#include <xnt_event.h>

ConnectMgr::ConnectMgr()
{
	alloc(1000);
}

ConnectMgr::ConnectMgr(int n)
{
	alloc(n);
}

ConnectMgr::~ConnectMgr()
{
	delete[] _pool;
}

void ConnectMgr::alloc(int n)
{
	int i;
	AxConnection *p;
	_count = 0;
	_max = n;
	_pool = new AxConnection[_max];
	_free_head = _pool;
	_max_vfd = 0;
	for(i=0, p=_pool; i<_max-1; i++, p++) {
		p->next = p+1;	
	}
	p->next = NULL;
}

//alloc a new connection
//@return vfd of connection pool(array offset), -1 for capacity full 
int ConnectMgr::alloc_connect(int sockfd, int type)
{
	int vfd;
	AxConnection* c = _free_head;
	if (_free_head == NULL) return -1;
	AX_ASSERT(type == OUTER_CLIENT || type == INNER_CLIENT);

	vfd = (int)(c - _pool);
	_free_head = c->next;
	c->fd = sockfd;
	c->wev.data = c->rev.data = (void*)vfd;
	c->rbuf->reset(1000);
	c->wbuf->reset(1000);
	_count--;
	c->type = type;
	if (vfd > _max_vfd) {
		_max_vfd = vfd;
	}
	return (int)(c - _pool);
}

void ConnectMgr::free_connect(int vfd)
{
	AxConnection* c;
	AX_ASSERT(vfd >= 0 && vfd < _max-1);
	c = &_pool[vfd];
	c->close();
	c->next = _free_head;
	c->type = CONN_INVALID;
	_free_head = c;
	if (vfd == _max_vfd) {
		_max_vfd--;
	}
}

AxConnection* ConnectMgr::get_connect(int vfd)
{
	if (vfd > _max-1 || vfd < 0) return NULL;
	return &_pool[vfd];	
}


//listener manager
//
ListenMgr::ListenMgr()
{

}

ListenMgr::~ListenMgr()
{

}

AxListen* ListenMgr::get_listener(int type)
{
	if (type == OUTER_LISTEN) {
		return &outer;
	} else if (type == INNER_LISTEN) {
		return &inner;
	}
	return NULL;
}

//unit test
IMPLEMENT_UTEST(conn_mgr)
{
	int ret;
	int vfd1, vfd2;
	ax_utest_log("begin conn_mgr unit test");
	ConnectMgr mgr(100);
	vfd1 = mgr.alloc_connect(1, OUTER_CLIENT);
	vfd2 = mgr.alloc_connect(2, OUTER_CLIENT);
	mgr.free_connect(vfd1);	
	UTEST_ASSERT(mgr.alloc_connect(3,OUTER_CLIENT) == 0);
	UTEST_ASSERT(mgr.alloc_connect(4,OUTER_CLIENT) == 2);	
	mgr.free_connect(1);
	UTEST_ASSERT(mgr.alloc_connect(5,OUTER_CLIENT) == 1);

	//listener
	AxListen ls;
	ret = ls.listen(10366, 5);
	UTEST_ASSERT(ret == 0);
	ax_utest_log("end conn_mgr test");
}
